﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Xml.Linq;

namespace FlickrCarousel
{
    public partial class CarouselItem : UserControl
    {
        public FlickrPhoto Photo { get; set; }

        public Boolean Flipped { get; set; }
        public Boolean Flipping { get; set; }

        public CarouselItem(FlickrPhoto photo)
        {
            InitializeComponent();

            Photo = photo;

            AddFlipAnimation();

            InfoPanel.ImageTitle.Text = Photo.Title;
            InfoPanel.ImageThumbnail.Source = new BitmapImage(new Uri(Photo.ImageUrl));

            ImageItem.Source = new BitmapImage(new Uri(photo.ImageUrl));
        }

        public void ShowFlipImage() {
            FlipImage.Visibility = Visibility.Visible;

            if (InfoPanel.ImageDescription.Text == null) {
                String url = String.Format("http://api.flickr.com/services/rest/?method=flickr.photos.getInfo&api_key={1}&photo_id={0}",
                        Photo.ID, (App.Current as App).APIKey, (App.Current as App).APISecret);
                WebClient flickrCall = new WebClient();
                flickrCall.DownloadStringCompleted += new DownloadStringCompletedEventHandler(flickrCall_DownloadStringCompleted);
                flickrCall.DownloadStringAsync(new Uri(url));
            }
        }

        void flickrCall_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e) {
            XDocument xmlPhotos = XDocument.Parse(e.Result);
            if (e.Error != null ||
                xmlPhotos.Element("rsp").Attribute("stat").Value == "fail") {
                string results = e.Result;
                return;
            }

            InfoPanel.ImageDescription.Text = xmlPhotos.Element("rsp").Element("photo").Element("description").Value;

            var urls = from url in xmlPhotos.Element("rsp").Element("photo").Element("urls").Elements("url")
                           select url;

            foreach (XElement url in urls) {
                if (url.Attribute("type").Value == "photopage") {
                    InfoPanel.ImageLink.NavigateUri = new Uri(url.Value);
                }
            }
        }
        public void HideFlipImage() {
            FlipImage.Visibility = Visibility.Collapsed;
        }

        void flipImage_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) {
            e.Handled = true;
            Flip(true);
        }
        public void Flip(Boolean toTheLeft) {
            if (!Flipping) {
                Storyboard storyboard = (Storyboard)this.Resources["rotate"];


                PlaneProjection projection = (PlaneProjection)Container.GetValue(UIElement.ProjectionProperty);
                if (projection.RotationY == 180.0 || projection.RotationY == -180.0) {
                    storyboard.Completed += new EventHandler(flipReverseFirstHalf_Completed);
                } else {
                    storyboard.Completed += new EventHandler(flipFirstHalf_Completed);
                }

                DoubleAnimation da0 = (DoubleAnimation)storyboard.Children[0];
                da0.From = null;
                da0.To = toTheLeft ? 90.0 : -90.0;

                if (!toTheLeft && projection.RotationY == 180)
                    projection.RotationY = -180.0;

                Flipping = true;
                storyboard.Begin();
            }
        }
        void flipFirstHalf_Completed(object sender, EventArgs e) {

            ImageItem.Visibility = Visibility.Collapsed;
            //image_bg.Visibility = Visibility.Collapsed;
            InfoPanel.Visibility = Visibility.Visible;
            FlipImage.HorizontalAlignment = HorizontalAlignment.Left;

            Double currentRotation = (Double)Container.Projection.GetValue(PlaneProjection.RotationYProperty);

            Storyboard storyboard = (Storyboard)this.Resources["rotate"];
            DoubleAnimation da0 = (DoubleAnimation)storyboard.Children[0];
            da0.From = currentRotation;
            da0.To = currentRotation == 90.0 ? 180.0 : -180.0;
            storyboard.Completed -= new EventHandler(flipFirstHalf_Completed);
            storyboard.Completed += new EventHandler(flipSecondHalf_Completed);
            storyboard.Begin();
        }
        void flipReverseFirstHalf_Completed(object sender, EventArgs e) {

            ImageItem.Visibility = Visibility.Visible;
            //image_bg.Visibility = Visibility.Visible;
            InfoPanel.Visibility = Visibility.Collapsed;
            FlipImage.HorizontalAlignment = HorizontalAlignment.Right;

            Double currentRotation = (Double)Container.Projection.GetValue(PlaneProjection.RotationYProperty);

            Storyboard storyboard = (Storyboard)this.Resources["rotate"];
            DoubleAnimation da0 = (DoubleAnimation)storyboard.Children[0];
            da0.From = currentRotation;
            da0.To = 0.0;
            storyboard.Completed -= new EventHandler(flipReverseFirstHalf_Completed);
            storyboard.Completed += new EventHandler(flipSecondHalf_Completed);
            storyboard.Begin();
        }
        void flipSecondHalf_Completed(object sender, EventArgs e) {
            Storyboard storyboard = (Storyboard)this.Resources["rotate"];
            storyboard.Completed -= new EventHandler(flipSecondHalf_Completed);
            PlaneProjection projection = (PlaneProjection)Container.GetValue(UIElement.ProjectionProperty);
            if (projection.RotationY == 180.0 || projection.RotationY == -180.0) {
                Flipped = true;
            } else {
                Flipped = false;
            }
            Flipping = false;
        }

        private void AddFlipAnimation() {

            Storyboard alterImage = new Storyboard();

            DoubleAnimation scaleRotateY = new DoubleAnimation();
            alterImage.Children.Add(scaleRotateY);
            scaleRotateY.Duration = new Duration(TimeSpan.FromSeconds(0.5));
            scaleRotateY.SetValue(Storyboard.TargetNameProperty, Container.Name);
            Storyboard.SetTarget(scaleRotateY, Container);
            Storyboard.SetTargetProperty(scaleRotateY,
                                         new PropertyPath("(UIElement.Projection).(PlaneProjection.RotationY)"));

            this.Resources.Add("rotate", alterImage);
        }

        void image_SizeChanged(object sender, SizeChangedEventArgs e) {
            if (sender is Image) {
                Image image = (Image)sender;

                if (image.ActualHeight < 400)
                    ImageGrid.Height = e.NewSize.Height;

                if (image.ActualHeight > 0 && image.ActualHeight != 5000) {

                    PlaceholderImage.Visibility = Visibility.Collapsed;

                    InfoPanel.Height = ImageGrid.Height;
                    InfoPanel.Visibility = Visibility.Visible;
                }
            }
        }

    }
}
